package com.shu.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.shu.domain.constant.DataSourceConstant;
import com.shu.domain.mybatis.DynamicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by shu on 2017/8/14.
 */
@Configuration
public class MybatisConfig implements EnvironmentAware {

    private Environment environment;


    @Bean
    public DataSource masterDataSource() throws Exception {

        Properties props = new Properties();
        props.put("driverClassName", environment.getProperty("datasource.master.driverClassName"));
        props.put("url", environment.getProperty("datasource.master.url"));
        props.put("username", environment.getProperty("datasource.master.username"));
        props.put("password", environment.getProperty("datasource.master.password"));
        return DruidDataSourceFactory.createDataSource(props);
    }


    @Bean
    public DataSource slaveDataSource() throws Exception {

        Properties props = new Properties();
        props.put("driverClassName", environment.getProperty("datasource.slave.driverClassName"));
        props.put("url", environment.getProperty("datasource.slave.url"));
        props.put("username", environment.getProperty("datasource.slave.username"));
        props.put("password", environment.getProperty("datasource.slave.password"));

        return DruidDataSourceFactory.createDataSource(props);

    }

    @Bean("dynamicDataSource")
    public DynamicDataSource dynamicDataSource() throws Exception {

        DynamicDataSource dynamicDataSource = new DynamicDataSource();

        DataSource master = masterDataSource();

        DataSource slave = slaveDataSource();

        Map<Object,Object> dsMap = new HashMap<>();

        dsMap.put(DataSourceConstant.MASTER_DATASOURCE,master);

        dsMap.put(DataSourceConstant.SLAVE_DATASOURCE,slave);

        dynamicDataSource.setTargetDataSources(dsMap);

        dynamicDataSource.setDefaultTargetDataSource(master);

        return dynamicDataSource;

    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factoryBean.setDataSource(dynamicDataSource);
        factoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
        factoryBean.setTypeAliasesPackage("com.**.domain");
        return factoryBean.getObject();
    }


    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.**.mapper");
        return mapperScannerConfigurer;
    }


    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dynamicDataSource) throws Exception {
        return new DataSourceTransactionManager(dynamicDataSource);
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
